package tms.unitTests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.TreeMap;

import org.junit.Before;
import org.junit.Test;

import tms.model.Task;
import tms.model.TaskTree;

/**
 * TaskTreeUnitTests class contains the units tests of the methods in the TaskTree class 
 * 
 * @author Amer Alhalabi
 *
 */
public class TaskTreeUnitTests {

	/// a header line used in writing the task tree to a csv file
	private static final String HEADER_STRING = "ID,Title,Description,Duration,Deliverable,Deadline,Person\n";
	
	/**
	 * helper method to access the DependencyManager tree map
	 */
	private TreeMap<Integer, Task> getTaskTreeMap() {
		TreeMap<Integer, Task> treeMap = new TreeMap<Integer, Task>();
		for (Map.Entry<Integer, Task>  entry : TaskTree.getInstance().getTaskMap().entrySet()) {
			treeMap.put(entry.getKey(), entry.getValue());
		}
		return treeMap;
	}

	/**
	 * default constructor
	 */
	public TaskTreeUnitTests() {
    }
	
	/**
	 * helper method to write a string to a file
	 * 
	 * @param fileName the name of the file to be written to 
	 * @param content content to be written to the file
	 */
	private void createFile( String fileName, String content) {
		PrintWriter printOut = null; 
		try {
			printOut = new PrintWriter(fileName); 
			printOut.print(content); 
			printOut.close();
		}
		catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		}
	}
	
	/**
	 * helper method to check if a file exists
	 * 
	 * @param fileName name of the file to be checked 
	 * 
	 * @return true if the file exists; false otherwise
	 */
	private boolean fileExists(String fileName) {
		File file = new File(fileName);
		return file.exists();
	}
	
	/**
	 * helper method to delete a file
	 * 
	 * @param fileName the name of the file to be deleted
	 */
	private void deleteFile(String fileName) {
		File file = new File(fileName);
		file.delete();
	}
	
	/**
	 * helper method to load the content of a file into a string
	 * 
	 * @param filename name of the file whose content is to be loaded
	 * 
	 * @return a string containing the content of the file 
	 */
	private String loadFileContent(String filename) {
		byte[] buffer = new byte[(int) new File(filename).length()];
	    BufferedInputStream f = null;
	    try {
	        f = new BufferedInputStream(new FileInputStream(filename));
	        f.read(buffer);
	    } catch (IOException e) {
			e.printStackTrace();
		} finally {
	        if (f != null) try { f.close(); } catch (IOException ignored) { }
	    }
	    return new String(buffer);
	}
	
	/**
	 * helper method called before every unit test to clear the taskTree
	 */
	@Before
    public void setUp() {
        TaskTree.getInstance().clear();
    }
	
	/**
	 * test that the only instance of the task tree is not null 
	 * and that it contains no person object
	 */
	@Test
	public void testTaskTreeGetInstance1() {
       
		TaskTree taskTree = TaskTree.getInstance();
		assertNotNull(taskTree);
		assertTrue(taskTree.getTasklist().isEmpty());
    }
	
	/**
	 * test that the getInstance() always returns the same instance of the taskTree no matter how
	 * many times it is called
	 */
	@Test
	public void testTaskTreeGetInstance2() {
       
		TaskTree taskTree1 = TaskTree.getInstance();
		TaskTree taskTree2 = TaskTree.getInstance();
		TaskTree taskTree3 = TaskTree.getInstance();
		
		assertNotNull(taskTree1);
		assertSame(taskTree1, taskTree2);
		assertSame(taskTree2, taskTree3);
    }
	
	/**
	 * test: the map of tasks and the list tasks in the task tree contain nothing when the taskTree is empty
	 */
	@Test
	public void testTaskTreeGetTaskList1() {
		
		int count1 = TaskTree.getInstance().getTaskMap().size();
		int count2 = TaskTree.getInstance().getTasklist().size();
		assertEquals(0, count1);
		assertEquals(0, count2);
	}
	
	/**
	 * test: the map of tasks and the list tasks in the taskTree contain
	 * the same task when the taskTree contains one task
	 */
	@Test 
	public void testTaskTreeGetTaskList2() {
		// creates a new task in the TaskTree
		Task task = TaskTree.getInstance().addTask();
		
		// expect the sizes to be equal
		int count1 = TaskTree.getInstance().getTaskMap().size();
		int count2 = TaskTree.getInstance().getTasklist().size();
		assertEquals(count1, count2);
		// expect the tasks in the map and in the list to be the same
		Task tmp1 = TaskTree.getInstance().getTaskMap().get(task.getId());
		Task tmp2 = TaskTree.getInstance().getTasklist().get(0);
		assertTrue(tmp1.equals(tmp2));
		assertTrue(tmp1.equals(task));
	}
	
	/**
	 * test: the map of tasks and the list tasks in the task tree contain
	 * the same tasks when the task tree is contains three tasks
	 */
	@Test  
	public void testTaskTreeGetTaskList3() {
	
		// Create 3 new tasks in the taskTree
		Task task1 = TaskTree.getInstance().addTask();
		Task task2 = TaskTree.getInstance().addTask();
		Task task3 = TaskTree.getInstance().addTask();

		// Set IDs of the new tasks
		task1.setId(1);
		task2.setId(2);
		task3.setId(3);
		
		// expect both the task map and task list to contain the same tasks
		int count1 = TaskTree.getInstance().getTaskMap().size();
		int count2 = TaskTree.getInstance().getTasklist().size();
		assertEquals(count1, count2);
		assertEquals(count1, 3);
		assertTrue(TaskTree.getInstance().getTasklist().contains(task1));
		assertTrue(TaskTree.getInstance().getTasklist().contains(task2));
		assertTrue(TaskTree.getInstance().getTasklist().contains(task3));
	}
	
	/**
	 * test adding a new task object to the task tree
	 * expect map of tasks has changed and now it contains the added task
	 */
	@Test
	public void testTaskTreeAddTask1() {
		// get the map of tasks before the attempt of the addition
		TreeMap<Integer, Task> tasksBefore = getTaskTreeMap();
		
		// create a task via TaskTree and get its instance
		Task task = TaskTree.getInstance().addTask();
		
		// get the map of tasks after the addition
		TreeMap<Integer, Task> tasksAfter = getTaskTreeMap();

		// expect the task has been added to the map
		assertFalse(tasksBefore.equals(tasksAfter));
		Task tmp = TaskTree.getInstance().getTaskMap().get(task.getId());
		assertTrue(task.equals(tmp));
	}
	
	/**
	 * test adding a new task and setting invalid ID to the task afterwards.
	 * expect map of tasks has changed and now it contains the added task
	 * however expect the id of the task to be set to a default value (zero)
	 */
	@Test 
	public void testTaskTreeAddTask2() {
		// get the map of tasks before the attempt of the addition
		TreeMap<Integer, Task> tasksBefore = getTaskTreeMap();
		
		/// create a task with negative id and add it to the taskTree
		Task task = TaskTree.getInstance().addTask();
		task.setId(-9);
		
		// get the map of tasks after the addition
		TreeMap<Integer, Task> tasksAfter = getTaskTreeMap();
		
		 // expect default task id is zero
		assertEquals(task.getId(), 0);
		
		// expect the task has been added to the map
		assertFalse(tasksBefore.equals(tasksAfter));
		Task tmp = TaskTree.getInstance().getTaskMap().get(task.getId());
		int count = TaskTree.getInstance().getTaskMap().size();
		assertTrue(task.equals(tmp));
		assertEquals(count , 1);
	}
	
	/**
	 * test adding three new tasks to the task tree
	 * expect map of tasks has changed and that it contains three task
	 */
	@Test 
	public void testTaskTreeAddTask3() {
		
		// get the map of tasks before the attempt of the addition
		TreeMap<Integer, Task> tasksBefore = getTaskTreeMap();
		
		// add first task the task tree
		Task task1 = TaskTree.getInstance().addTask();
		
		// get the map of tasks after the addition of the first task
		TreeMap<Integer, Task> tasksMid1 = getTaskTreeMap();
		
		// add second task the task tree
		Task task2 = TaskTree.getInstance().addTask();

		// get the map of tasks after the addition of the second task
		TreeMap<Integer, Task> tasksMid2 = getTaskTreeMap();
		
		// add third task the task tree
		Task task3 = TaskTree.getInstance().addTask();

		// get the map of tasks after the addition of the third task
		TreeMap<Integer, Task> tasksAfter = getTaskTreeMap();
		
		task1.setId(1);
		task2.setId(2);
		task3.setId(3);				
				
		// expect the map of tasks to contain all three tasks
		assertFalse(tasksBefore.equals(tasksMid1));
		assertFalse(tasksMid1.equals(tasksMid2));
		assertFalse(tasksMid2.equals(tasksAfter));
		assertFalse(tasksBefore.equals(tasksAfter));
		
		int count = TaskTree.getInstance().getTaskMap().size();
		assertEquals(count , 3);
	}
	
	/**
	 * test removing a null task from the task tree.
	 * expect no change to the task tree
	 */
	@Test 
	public void testTaskTreeRemoveTask1() {
		
		// get the map of tasks before the attempt of the removal
		TreeMap<Integer, Task> tasksBefore= TaskTree.getInstance().getTaskMap();
		
		// remove a null task from the task tree
		TaskTree.getInstance().removeTask(null);
		
		// get the map of tasks after the removal
		TreeMap<Integer, Task> tasksAfter= TaskTree.getInstance().getTaskMap();
		
		// expect no change to the task tree
		assertTrue(tasksBefore.equals(tasksAfter));
	}
	
	/**
	 * test removing a task from the task tree, but the task does not exist in the task tree
	 * expect no change to the task tree
	 */
	@Test 
	public void testTaskTreeRemoveTask2() {
		
		// get the map of tasks before the attempt of the removal
		TreeMap<Integer, Task> tasksBefore= TaskTree.getInstance().getTaskMap();
		
		// create a task and try to remove it from the task tree
		Task task1 = new Task();
		task1.setId(1);
		TaskTree.getInstance().removeTask(task1);
		
		// get the map of tasks after the attempt of the removal
		TreeMap<Integer, Task> tasksAfter= TaskTree.getInstance().getTaskMap();
		
		// expect no change to the task tree
		assertTrue(tasksBefore.equals(tasksAfter));
	}

	/**
	 * test removing one task from the task tree that has only that task
	 * expect the task tree to be empty after the removal
	 */
	@Test 
	public void testTaskTreeRemoveTask3() {
		
		// get the map of tasks before the attempt of the removal
		TreeMap<Integer, Task> tasksBefore= TaskTree.getInstance().getTaskMap();
		
		// add a new task to the task tree
		Task task = TaskTree.getInstance().addTask();
		
		// remove the task from the task tree
		TaskTree.getInstance().removeTask(task);
		
		// get the map of tasks after the attempt of the removal
		TreeMap<Integer, Task> tasksAfter= TaskTree.getInstance().getTaskMap();
		
		// expect the task tree to be empty
		assertTrue(tasksBefore.equals(tasksAfter));
		int count = TaskTree.getInstance().getTaskMap().size();
		assertEquals(count , 0);
		assertTrue(TaskTree.getInstance().getTaskMap().isEmpty());
	}
	
	/**
	 * test removing one task from the task tree that has many tasks
	 * expect the task tree to be NON-empty after the removal, and it does not contain the removed task 
	 */
	@Test
	public void testTaskTreeRemoveTask4() {
		
		// get the map of tasks before the attempt of the removal
		TreeMap<Integer, Task> tasksBefore = getTaskTreeMap();
		
		// create three tasks and add them to the task tree
		Task task1 = TaskTree.getInstance().addTask();
		Task task2 = TaskTree.getInstance().addTask();
		Task task3 = TaskTree.getInstance().addTask();
		task1.setId(1);
		task2.setId(2);
		task3.setId(3);
		
		// get the map of tasks after the addition of the tasks
		TreeMap<Integer, Task> tasksMid = getTaskTreeMap();
		
		// remove task1
		TaskTree.getInstance().removeTask(task1);
		
		// get the map of tasks after the attempt of the removal
		TreeMap<Integer, Task> tasksAfter = getTaskTreeMap();
		
		// expect the task tree to contain only task2 and task3
		assertFalse(tasksBefore.equals(tasksMid));
		assertFalse(tasksMid.equals(tasksAfter));
		assertFalse(tasksBefore.equals(tasksAfter));
		int count = TaskTree.getInstance().getTaskMap().size();
		assertEquals(count , 2);
		assertNull(TaskTree.getInstance().getTaskMap().get(task1.getId()));
	}
	
	/**
	 * test removing the same task twice from the task tree that has many tasks
	 * expect the tasktree to be NON-empty after the removal, and it does not contain the removed task
	 * and that the removal of the same task twice did not impact other tasks 
	 */
	@Test
	public void testTaskTreeRemoveTask5() {
		
		// get the map of tasks before the attempt of the removal
		TreeMap<Integer, Task> tasksBefore = getTaskTreeMap();
		
		// create three different tasks and add them to the task tree
		Task task1 = TaskTree.getInstance().addTask();
		Task task2 = TaskTree.getInstance().addTask();
		Task task3 = TaskTree.getInstance().addTask();

		// get the map of tasks after the additions
		TreeMap<Integer, Task> tasksMid1 = getTaskTreeMap();
		
		// remove task1
		TaskTree.getInstance().removeTask(task1);
		TreeMap<Integer, Task> tasksMid2 = getTaskTreeMap();
		
		// remove task1 again
		TaskTree.getInstance().removeTask(task1);
		// get the map of tasks after the attempt of the removal
		TreeMap<Integer, Task> tasksAfter = getTaskTreeMap();
		
		// expect that the tasktree does not contain task1 and that it contains task2 and task3
		assertFalse(tasksBefore.equals(tasksMid1));
		assertFalse(tasksMid1.equals(tasksMid2));
		assertFalse(tasksBefore.equals(tasksAfter));
		assertTrue(tasksMid2.equals(tasksAfter));
		int count = TaskTree.getInstance().getTaskMap().size();
		assertEquals(count , 2);
		assertNull(TaskTree.getInstance().getTaskMap().get(task1.getId()));
		assertNotNull(TaskTree.getInstance().getTaskMap().get(task2.getId()));
		assertNotNull(TaskTree.getInstance().getTaskMap().get(task3.getId()));
	}
	
	/**
	 * test loading description of tasks from an empty xml file
	 * expect an unsuccessful operation and that the task tree and people table are empty 
	 */
	@Test
	public void testTaskTreeLoadXmlFile1() {
		
		String filename = "test.xml";
		String content = "";
		// create an empty input xml file
		createFile(filename, content);
		
		// expect failure 
		TaskTree taskTree = TaskTree.getInstance();
		assertFalse(taskTree.loadXMLFile(filename));
		
		// expect empty tables
		assertTrue(taskTree.getTasklist().isEmpty());
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that does not exist
	 * expect an unsuccessful operation and that the task tree and people table are empty 
	 */
	@Test
	public void testTaskTreeLoadXmlFile2() {
		
		// try to load a file that does not exist
		// expect failure 
		String filename = "doesNotExist.xml";
		TaskTree taskTree = TaskTree.getInstance(); 
		assertFalse(taskTree.loadXMLFile(filename));
		
		// expect empty tables
		assertTrue(taskTree.getTasklist().isEmpty());
	}
	

	/**
	 * test loading description of tasks from a file name that is a empty string
	 * expect an unsuccessful operation and that the task tree and people table are empty 
	 */
	@Test
	public void testTaskTreeLoadXmlFile3() {
		
		// empty filename
		String filename = "";
		TaskTree taskTree = TaskTree.getInstance(); 

		// try to load the file
		// expect failure 
		assertFalse(taskTree.loadXMLFile(filename));
		
		// expect empty tables
		assertEquals(0, taskTree.getTasklist().size());
		
	}
	
	/**
	 * test loading description of tasks from a file name that is null
	 * expect an unsuccessful operation and that the task tree and people table are empty 
	 */
	@Test 
	public void testTaskTreeLoadXmlFile4() {
	
		String filename = null;
		TaskTree taskTree = TaskTree.getInstance(); 
		
		// try to load the file
		// expect failure 
		assertFalse(taskTree.loadXMLFile(filename));
		
		// expect empty tables
		assertEquals(0, taskTree.getTasklist().size());
	}
	
	/**
	 * test loading description of tasks from a file that contains one task
	 * expect a successful operation and that the task tree contains one task (equal to the one in the file)
	 * expect  people table contain one person whose name is the same as the task's person name in the file 
	 */
	@Test 
	public void testTaskTreeLoadXmlFile5() {
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n"; 
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance(); 
		assertTrue(taskTree.loadXMLFile(filename));
		
		// expect the task tree to contain one task
		assertEquals(taskTree.getTasklist().size(), 1);
		
		// make sure that the task loaded into the task tree is equal to the one in the file
		assertTrue(taskTree.getTaskMap().get(1).getTitle().equals("Iteration 1"));
		assertTrue(taskTree.getTaskMap().get(1).getDescription().equals("The first iteration of the project, including requirements document and source code"));
		assertTrue(taskTree.getTaskMap().get(1).getDuration() == 2);
		assertTrue(taskTree.getTaskMap().get(1).getDeliverable().equals("Requirements document"));
		System.out.println(taskTree.getTaskMap().get(1).getDeadline().toString());
		assertTrue(taskTree.getTaskMap().get(1).getDeadline().toString().equals("Fri Jan 27 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(1).getPerson().equals("Person 1"));
		
		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that contains many tasks
	 * and that there are at least two tasks assigned to the same person
	 * 
	 * expect a successful operation and that the task tree contains all tasks described in the file
	 * expect  people table contain all persons whose names are described in the file 
	 */
	@Test
	public void testTaskTreeLoadXmlFile6() {
		// create a file with three tasks
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>des1</description>\n";
		content += "\t\t<duration>1</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>des2</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del2</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>3</id>\n";
		content += "\t\t<title>Iteration 3</title>\n";
		content += "\t\t<description>des3</description>\n";
		content += "\t\t<duration>3</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del3</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";  
		
		createFile(filename, content);
		
		// load the file
		TaskTree taskTree = TaskTree.getInstance(); 
		assertTrue(taskTree.loadXMLFile(filename));
		
		// expect the task tree to contain three tasks
		assertEquals(taskTree.getTasklist().size(), 3);

		// verify that the tasks that were added to the task tree have the same attributes described in the file
		assertTrue(taskTree.getTaskMap().get(1).getTitle().equals("Iteration 1"));
		assertTrue(taskTree.getTaskMap().get(1).getDescription().equals("des1"));
		assertTrue(taskTree.getTaskMap().get(1).getDuration() == 1);
		assertTrue(taskTree.getTaskMap().get(1).getDeliverable().equals("del1"));
		assertTrue(taskTree.getTaskMap().get(1).getDeadline().toString().equals("Fri Jan 27 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(1).getPerson().equals("Person 1"));
		
		assertTrue(taskTree.getTaskMap().get(2).getTitle().equals("Iteration 2"));
		assertTrue(taskTree.getTaskMap().get(2).getDescription().equals("des2"));
		assertTrue(taskTree.getTaskMap().get(2).getDuration() == 2);
		assertTrue(taskTree.getTaskMap().get(2).getDeliverable().equals("del2"));
		assertTrue(taskTree.getTaskMap().get(2).getDeadline().toString().equals("Fri Jan 27 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(2).getPerson().equals("Person 2"));
		
		assertTrue(taskTree.getTaskMap().get(3).getTitle().equals("Iteration 3"));
		assertTrue(taskTree.getTaskMap().get(3).getDescription().equals("des3"));
		assertTrue(taskTree.getTaskMap().get(3).getDuration() == 3);
		assertTrue(taskTree.getTaskMap().get(3).getDeliverable().equals("del3"));
		assertTrue(taskTree.getTaskMap().get(3).getDeadline().toString().equals("Fri Jan 27 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(3).getPerson().equals("Person 1"));
		
		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that contains many tasks and subtasks
	 * and that there are at least two tasks assigned to the same person
	 * and that some tasks are assigned to nobody
	 * 
	 * expect a successful operation and that the task tree contains all tasks and subtasks described in the file
	 * expect  people table contain all persons whose names are described in the file 
	 */
	@Test   
	public void testTaskTreeLoadXmlFile7() {
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The second iteration of the project, including design document and source code</description>\n";
		content += "\t\t<duration>4</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Design document</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t\t<subtasks>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>3</id>\n";
		content += "\t\t\t\t<title>Iteration 2.1</title>\n";
		content += "\t\t\t\t<description>21 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>21 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>4</id>\n";
		content += "\t\t\t\t<title>Iteration 2.2</title>\n";
		content += "\t\t\t\t<description>22 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>22 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t<subtasks>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>5</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.1</title>\n";
		content += "\t\t\t\t\t\t<description>221 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>221 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>6</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.2</title>\n";
		content += "\t\t\t\t\t\t<description>222 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>222 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t</subtasks>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t</subtasks>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>7</id>\n";
		content += "\t\t<title>Iteration 3</title>\n";
		content += "\t\t<description>The third iteration of the project, including test plan, report document and source code</description>\n";
		content += "\t\t<duration>30</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Test plan and report document</deliverable>\n";
		content += "\t\t<person>Person 3</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>8</id>\n";
		content += "\t\t<title>Iteration 4</title>\n";
		content += "\t\t<description>The final iteration of the project (complete system)</description>\n";
		content += "\t\t<duration>14</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Complete system</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(filename));
		
		// make sure the tasks and subtasks were added based on their IDs
		assertTrue(taskTree.getTaskMap().containsKey(1));
		assertTrue(taskTree.getTaskMap().containsKey(2));
		assertTrue(taskTree.getTaskMap().containsKey(3));
		assertTrue(taskTree.getTaskMap().containsKey(4));
		assertTrue(taskTree.getTaskMap().containsKey(5));
		assertTrue(taskTree.getTaskMap().containsKey(6));
		assertTrue(taskTree.getTaskMap().containsKey(7));
		assertTrue(taskTree.getTaskMap().containsKey(8));
		
		// verify that tasks and subtasks have valid info
		assertTrue(taskTree.getTaskMap().get(1).getTitle().equals("Iteration 1"));
		assertTrue(taskTree.getTaskMap().get(1).getDescription().equals("The first iteration of the project, including requirements document and source code"));
		assertTrue(taskTree.getTaskMap().get(1).getDuration() == 2);
		assertTrue(taskTree.getTaskMap().get(1).getDeliverable().equals("Requirements document"));
		assertTrue(taskTree.getTaskMap().get(1).getDeadline().toString().equals("Fri Jan 27 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(1).getPerson().equals("Person 1"));
		
		assertTrue(taskTree.getTaskMap().get(2).getTitle().equals("Iteration 2"));
		assertTrue(taskTree.getTaskMap().get(2).getDescription().equals("The second iteration of the project, including design document and source code"));
		assertTrue(taskTree.getTaskMap().get(2).getDuration() == 4);
		assertTrue(taskTree.getTaskMap().get(2).getDeliverable().equals("Design document"));
		assertTrue(taskTree.getTaskMap().get(2).getDeadline().toString().equals("Fri Feb 24 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(2).getPerson().equals("Person 2"));
		
		assertTrue(taskTree.getTaskMap().get(3).getTitle().equals("Iteration 2.1"));
		assertTrue(taskTree.getTaskMap().get(3).getDescription().equals("21 description"));
		assertTrue(taskTree.getTaskMap().get(3).getDuration() == 1);
		assertTrue(taskTree.getTaskMap().get(3).getDeliverable().equals("21 deliverable"));
		assertTrue(taskTree.getTaskMap().get(3).getPerson().equals("Person 2"));
		
		assertTrue(taskTree.getTaskMap().get(4).getTitle().equals("Iteration 2.2"));
		assertTrue(taskTree.getTaskMap().get(4).getDescription().equals("22 description"));
		assertTrue(taskTree.getTaskMap().get(4).getDuration() == 1);
		assertTrue(taskTree.getTaskMap().get(4).getDeliverable().equals("22 deliverable"));
		assertTrue(taskTree.getTaskMap().get(4).getPerson().equals("Person 2"));
		
		assertTrue(taskTree.getTaskMap().get(5).getTitle().equals("Iteration 2.2.1"));
		assertTrue(taskTree.getTaskMap().get(5).getDescription().equals("221 description"));
		assertTrue(taskTree.getTaskMap().get(5).getDuration() == 1);
		assertTrue(taskTree.getTaskMap().get(5).getDeliverable().equals("221 deliverable"));
		assertTrue(taskTree.getTaskMap().get(5).getPerson().equals("Person 2"));
		
		assertTrue(taskTree.getTaskMap().get(6).getTitle().equals("Iteration 2.2.2"));
		assertTrue(taskTree.getTaskMap().get(6).getDescription().equals("222 description"));
		assertTrue(taskTree.getTaskMap().get(6).getDuration() == 1);
		assertTrue(taskTree.getTaskMap().get(6).getDeliverable().equals("222 deliverable"));
		assertTrue(taskTree.getTaskMap().get(6).getPerson().equals("Person 2"));
		
		assertTrue(taskTree.getTaskMap().get(7).getTitle().equals("Iteration 3"));
		assertTrue(taskTree.getTaskMap().get(7).getDescription().equals("The third iteration of the project, including test plan, report document and source code"));
		assertTrue(taskTree.getTaskMap().get(7).getDuration() == 30);
		assertTrue(taskTree.getTaskMap().get(7).getDeliverable().equals("Test plan and report document"));
		assertTrue(taskTree.getTaskMap().get(7).getDeadline().toString().equals("Fri Feb 24 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(7).getPerson().equals("Person 3"));
		
		assertTrue(taskTree.getTaskMap().get(8).getTitle().equals("Iteration 4"));
		assertTrue(taskTree.getTaskMap().get(8).getDescription().equals("The final iteration of the project (complete system)"));
		assertTrue(taskTree.getTaskMap().get(8).getDuration() == 14);
		assertTrue(taskTree.getTaskMap().get(8).getDeliverable().equals("Complete system"));
		assertTrue(taskTree.getTaskMap().get(8).getDeadline().toString().equals("Fri Feb 24 00:00:00 EST 2012"));
		assertTrue(taskTree.getTaskMap().get(8).getPerson().equals("Person 1"));
		
		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that contains duplicate tasks (tasks with same id)
	 *  
	 * expect an unsuccessful operation and that the task tree and people table are empty 
	 */
	@Test
	public void testTaskTreeLoadXmlFile8() {
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>what's up test</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>8</duration>\n";
		content += "\t\t<deliverable>model document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t</task>\n";
		
		// dupilcate
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";   //a duplicate
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>cool</description>\n";
		content += "\t\t<duration>10</duration>\n";
		content += "\t\t<deliverable>Design document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t</task>\n";
		content += "</data>\n";  
		
		createFile(filename, content);
		
		TaskTree taskTree = TaskTree.getInstance(); 
		
		//load file
		assertFalse(taskTree.loadXMLFile(filename));
		
		// expect task tree and people table to be empty
		assertEquals(0, taskTree.getTasklist().size());
		
		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that contains tasks with missing attributes
	 *  
	 * expect an unsuccessful operation and that the task tree and people table are empty 
	 */
	@Test 
	public void testTaskTreeLoadXmlFile9() {
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		// missing title
		content += "\t\t<description>what's up test</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		// missing duration
		content += "\t\t<deliverable>model document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>3</id>\n";   
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>cool</description>\n";
		content += "\t\t<duration>10</duration>\n";
		content += "\t\t<deliverable>Design document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		// missing person
		content += "\t</task>\n";
		content += "</data>\n"; 
		
		createFile(filename, content);
		
		// load file
		TaskTree taskTree = TaskTree.getInstance(); 
		assertFalse(taskTree.loadXMLFile(filename));
		
		// expect empty task and people tables 
		assertEquals(0, taskTree.getTasklist().size());
		
		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that contains invalid xml format
	 *  
	 * expect an unsuccessful operation and that the task tree and people table are empty 
	 */
	@Test
	public void testTaskTreeLoadXmlFile10() {
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</\n"; // invalid closing tag
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>what's up test</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>8</duration>\n";
		content += "\t\t<deliverable>model document</deliverable>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t</task>\n";
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load file
		TaskTree taskTree = TaskTree.getInstance(); 
		assertFalse(taskTree.loadXMLFile(filename));
		
		// expect empty task and people tables 
		assertEquals(0, taskTree.getTasklist().size());
		
		//clean up
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that contains many tasks and subtasks
	 * but at least one of the subtasks has a subtask that is tagged "accidently" as <task> instead of <subtask>.
	 * expect unsuccessful operation and that the task tree is empty 
	 */
	@Test   
	public void testTaskTreeLoadXmlFile11() {
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";

		content += "\t\t<subtasks>\n";
		content += "\t\t\t<task>\n";  //here 
		content += "\t\t\t\t<id>3</id>\n";
		content += "\t\t\t\t<title>Iteration 2.1</title>\n";
		content += "\t\t\t\t<description>21 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>21 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t</task>\n";
		
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>4</id>\n";
		content += "\t\t\t\t<title>Iteration 2.2</title>\n";
		content += "\t\t\t\t<description>22 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>22 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t</subtask>\n";
		
		content += "\t\t</subtasks>\n";
		content += "\t</task>\n";
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertFalse(taskTree.loadXMLFile(filename));
		// expect empty task and people tables 
		assertEquals(0, taskTree.getTasklist().size());
		
		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test loading description of tasks from a file that contains many tasks and subtasks
	 * but at least one of the subtasks has a beforeId != -1 
	 * expect unsuccessful operation and that the task tree is empty 
	 */
	@Test   
	public void testTaskTreeLoadXmlFile12() {
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";

		content += "\t\t<subtasks>\n";
		content += "\t\t\t<subtask>\n";  
		content += "\t\t\t\t<id>3</id>\n";
		content += "\t\t\t\t<title>Iteration 2.1</title>\n";
		content += "\t\t\t\t<description>21 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>21 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>4</before>\n";  ///
		content += "\t\t\t</subtask>\n";
		
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>4</id>\n";
		content += "\t\t\t\t<title>Iteration 2.2</title>\n";
		content += "\t\t\t\t<description>22 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>22 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t</subtask>\n";
		
		content += "\t\t</subtasks>\n";
		content += "\t</task>\n";
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertFalse(taskTree.loadXMLFile(filename));
		// expect empty task and people tables 
		assertEquals(0, taskTree.getTasklist().size());
		
		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test saving task tree into a CSV file; where the filename is null
	 *  
	 * expect an unsuccessful operation and that no CSV file is created
	 */
	@Test
	public void testTaskTreeSaveCSVFile1() {
		String filename = null;
		TaskTree taskTree = TaskTree.getInstance();
		assertFalse(taskTree.saveCSVFile(filename));
	}
	
	/**
	 * test saving task tree into a CSV file; where the filename is an empty string
	 *  
	 * expect an unsuccessful operation and that no CSV file is created
	 */
	@Test
	public void testTaskTreeSaveCSVFile2() {
		String filename = "";
		TaskTree taskTree = TaskTree.getInstance();
		assertFalse(taskTree.saveCSVFile(filename));
	}
	
	/**
	 * test saving task tree into a CSV file; where the file already exist
	 *  
	 * expect a successful operation and that the content of the file is overwritten with the content of the task tree
	 */
	@Test
	public void testTaskTreeSaveCSVFile3() {
		
		// create an input xml file and an output csv file
		String infilename = "test.xml";
		String outFilename = "out.csv";
		
		// create input xml file
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>des1</description>\n";
		content += "\t\t<duration>1</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>des2</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";

		createFile(infilename, content);
		createFile(outFilename, "");  // create an output file
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(infilename));
		
		// expect the successful population of tasks and person
		assertEquals(taskTree.getTasklist().size(), 2);
		
		// save the task tree into an CSV file
		assertTrue(taskTree.saveCSVFile(outFilename));
		assertTrue(fileExists(outFilename));
		
		// verify the content of the csv file
		String cont = null;
		cont = loadFileContent(outFilename);
		String expected = "ID,Title,Description,Duration,Deliverable,Deadline,Person\n" +
				"1,Iteration 1,des1,1,del1,Fri Jan 27 00:00:00 EST 2012,Person 1\n" +
				"2,Iteration 2,des2,2,del1,Fri Jan 27 00:00:00 EST 2012,Person 2\n";
		assertTrue(cont.equals(expected));
		
		deleteFile(infilename);
		deleteFile(outFilename);
	}
	
	/**
	 * test saving task tree into a CSV file; when the task tree is empty
	 *  
	 * expect a successful operation and that the content of the file is only a header describing the fields
	 */
	@Test
	public void testTaskTreeSaveCSVFile4(){
		
		String outFilename = "out.csv";
		// make sure the task tree is empty
		TaskTree taskTree = TaskTree.getInstance();
		assertEquals(taskTree.getTasklist().size(), 0);
		
		// save the task tree to a CSV file
		assertTrue(taskTree.saveCSVFile(outFilename));
		assertTrue(fileExists(outFilename));
		
		// verify that the content is only the header
		String cont = loadFileContent(outFilename);
		assertTrue(cont.equals(HEADER_STRING));
		
		// clean up
		deleteFile(outFilename);
	}
	
	/**
	 * test saving a non-empty task tree into a CSV file
	 *  
	 * expect a successful operation and that the content of the file contains a header describing the fields
	 * and the tasks
	 */
	@Test
	public void testTaskTreeSaveCSVFile5() {
		String infilename = "test.xml";
		String outFilename = "out.csv";
		
		// create input xml file
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>des1</description>\n";
		content += "\t\t<duration>1</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>des2</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";

		createFile(infilename, content);
		
		// load the input xml file
		// verify the successful loading
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(infilename));
		assertEquals(taskTree.getTasklist().size(), 2);
		
		// save the task tree to a CSV file
		assertTrue(taskTree.saveCSVFile(outFilename));
		assertTrue(fileExists(outFilename));
		
		// verify the content
		String cont = null;
		cont = loadFileContent(outFilename);
		String expected = "ID,Title,Description,Duration,Deliverable,Deadline,Person\n" +
				"1,Iteration 1,des1,1,del1,Fri Jan 27 00:00:00 EST 2012,Person 1\n" +
				"2,Iteration 2,des2,2,del1,Fri Jan 27 00:00:00 EST 2012,Person 2\n";
		assertTrue(cont.equals(expected));
		
		// clean up
		deleteFile(infilename);
		deleteFile(outFilename);
	}
	
	/**
	 * test getting a task by passing a negative id
	 *  
	 * expect to receive null as return
	 */
	@Test
	public void testTaskTreeGetTask1(){
		TaskTree taskTree = TaskTree.getInstance();
		
		taskTree.addTask();

		assertNull(taskTree.getTask(-1));
	}

	/**
	 * test getting a task by passing zero after adding one task to the TaskTree
	 *  
	 * expect to receive a valid task object as return
	 */
	@Test
	public void testTaskTreeGetTask2(){
		TaskTree taskTree = TaskTree.getInstance();
		
		taskTree.addTask();

		assertNotNull(taskTree.getTask(0));
	}

	/**
	 * test getting a task by passing zero without adding a task to the TaskTree
	 *  
	 * expect to receive null as return
	 */
	@Test
	public void testTaskTreeGetTask3(){
		TaskTree taskTree = TaskTree.getInstance();

		assertNull(taskTree.getTask(0));
	}

	/**
	 * test getting a task by passing an id that does not exist
	 *  
	 * expect to receive null as return
	 */
	@Test
	public void testTaskTreeGetTask4(){
		TaskTree taskTree = TaskTree.getInstance();
		
		taskTree.addTask();

		assertNull(taskTree.getTask(1));
	}

	/**
	 * test getting a task by passing an id that exists
	 *  
	 * expect to receive a valid task object as return
	 */
	@Test
	public void testTaskTreeGetTask5(){
		TaskTree taskTree = TaskTree.getInstance();
		
		taskTree.addTask(); // id = 0
		taskTree.addTask(); // id = 1
		taskTree.addTask(); // id = 2

		assertNotNull(taskTree.getTask(2));
	}

	/**
	 * clear an empty TaskTree
	 */
	@Test
	public void testTaskTreeClear1() {
		TaskTree taskTree = TaskTree.getInstance();

		taskTree.clear();
		assertEquals(0, taskTree.getTasklist().size());
		assertEquals(0, taskTree.getTaskMap().size());
	}

	/**
	 * clear a non-empty empty TaskTree
	 */
	@Test
	public void testTaskTreeClear2() {
		TaskTree taskTree = TaskTree.getInstance();

		taskTree.addTask(); // id = 0
		taskTree.addTask(); // id = 1
		taskTree.addTask(); // id = 2

		taskTree.clear();
		assertEquals(0, taskTree.getTasklist().size());
		assertEquals(0, taskTree.getTaskMap().size());
	}
	
	/**
	 * test adding a subtask to a task when the task is null
	 */
	@Test
	public void testTaskTreeAddSubTask1() {
		
		TaskTree taskTree = TaskTree.getInstance();
		assertEquals(0, taskTree.getTasklist().size());
		taskTree.addTask(); // id = 0
		taskTree.addTask(); // id = 1
		taskTree.addTask(); // id = 2
		assertEquals(3, taskTree.getTasklist().size());
		
		taskTree.addSubtask(null);
		assertEquals(3, taskTree.getTaskMap().size());
	}
	
	/**
	 * test adding a subtask to a task that was added to the tree before
	 */
	@Test
	public void testTaskTreeAddSubTask2() {
		
		TaskTree taskTree = TaskTree.getInstance();
		assertEquals(0, taskTree.getTasklist().size());
		taskTree.addTask(); // id = 0
		taskTree.addTask(); // id = 1
		taskTree.addTask(); // id = 2
		assertEquals(3, taskTree.getTasklist().size());
		
		taskTree.addSubtask(taskTree.getTask(0)); // subtask id = 3
		assertEquals(4, taskTree.getTaskMap().size());
		assertEquals(1, taskTree.getTask(0).getSubtasks().size());
		assertTrue( taskTree.getTask(0).getSubtasks().contains(taskTree.getTask(3)));
	}
	
	/**
	 * test adding a subtask to a task that was not added to the tree before
	 * nothing will be added
	 */
	@Test
	public void testTaskTreeAddSubTask3() {
		
		TaskTree taskTree = TaskTree.getInstance();
		assertEquals(0, taskTree.getTasklist().size());
		taskTree.addTask(); // id = 0
		taskTree.addTask(); // id = 1
		taskTree.addTask(); // id = 2
		assertEquals(3, taskTree.getTasklist().size());
		
		Task temp = new Task();
		temp.setId(10);
		
		taskTree.addSubtask(temp); // subtask id = 3
		assertEquals(3, taskTree.getTaskMap().size());
		assertFalse( taskTree.getTaskMap().containsKey(temp.getId()));
		assertFalse( taskTree.getTaskMap().containsKey(3));
		assertFalse( temp.getSubtasks().contains(taskTree.getTask(3)));
	}
	
	/**
	 * test adding a subtask to a task that was added to the tree before and has some subtasks already
	 */
	@Test
	public void testTaskTreeAddSubTask4() {
		
		TaskTree taskTree = TaskTree.getInstance();
		assertEquals(0, taskTree.getTasklist().size());
		taskTree.addTask(); // id = 0
		taskTree.addTask(); // id = 1
		taskTree.addTask(); // id = 2
		assertEquals(3, taskTree.getTasklist().size());
		
		taskTree.addSubtask(taskTree.getTask(0)); // subtask id = 3
		taskTree.addSubtask(taskTree.getTask(0)); // subtask id = 4
		taskTree.addSubtask(taskTree.getTask(0)); // subtask id = 5
		
		assertEquals(6, taskTree.getTaskMap().size());
		assertTrue( taskTree.getTaskMap().containsKey(3));
		assertTrue( taskTree.getTaskMap().containsKey(4));
		assertTrue( taskTree.getTaskMap().containsKey(5));
		assertTrue( taskTree.getTask(0).getSubtasks().contains(taskTree.getTask(3)));
		assertTrue( taskTree.getTask(0).getSubtasks().contains(taskTree.getTask(4)));
		assertTrue( taskTree.getTask(0).getSubtasks().contains(taskTree.getTask(5)));
	}
	
	/**
	 * test: getting top level tasks when the tasktree is empty
	 */
	@Test
	public void testTaskTreeGetTopLevelTasklist1() {

		int count = TaskTree.getInstance().getTopLevelTasklist().size();
		assertEquals(0, count);
	}
	
	/**
	 * test: getting top level tasks when the tasktree contains only top level tasks
	 */
	@Test 
	public void testTaskTreeGetTopLevelTasklist2() {
		
		// create a file
		String filename = "test.xml";
		
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		
		content += "<data>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The second iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>5</duration>\n";
		content += "\t\t<deadline>2012-01-30</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>3</id>\n";
		content += "\t\t<title>Iteration 3</title>\n";
		content += "\t\t<description>The third iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>19</duration>\n";
		content += "\t\t<deadline>2012-01-30</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 3</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(filename));
		// expect empty task and people tables 
		assertEquals(3, taskTree.getTasklist().size());
				
		// expect the sizes to be equal
		int count = TaskTree.getInstance().getTopLevelTasklist().size();
		assertEquals(3, count);

		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test: getting top level tasks when the tasktree contains different levels of  tasks
	 */
	@Test  
	public void testTaskTreeGetTopLevelTasklist3() {
		
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The second iteration of the project, including design document and source code</description>\n";
		content += "\t\t<duration>4</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Design document</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t\t<subtasks>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>3</id>\n";
		content += "\t\t\t\t<title>Iteration 2.1</title>\n";
		content += "\t\t\t\t<description>21 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>21 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>4</id>\n";
		content += "\t\t\t\t<title>Iteration 2.2</title>\n";
		content += "\t\t\t\t<description>22 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>22 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t<subtasks>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>5</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.1</title>\n";
		content += "\t\t\t\t\t\t<description>221 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>221 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>6</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.2</title>\n";
		content += "\t\t\t\t\t\t<description>222 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>222 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t</subtasks>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t</subtasks>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>7</id>\n";
		content += "\t\t<title>Iteration 3</title>\n";
		content += "\t\t<description>The third iteration of the project, including test plan, report document and source code</description>\n";
		content += "\t\t<duration>30</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Test plan and report document</deliverable>\n";
		content += "\t\t<person>Person 3</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>8</id>\n";
		content += "\t\t<title>Iteration 4</title>\n";
		content += "\t\t<description>The final iteration of the project (complete system)</description>\n";
		content += "\t\t<duration>14</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Complete system</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(filename));
		
		// make sure the tasks and subtasks were added based on their IDs
		assertTrue(taskTree.getTaskMap().containsKey(1));
		assertTrue(taskTree.getTaskMap().containsKey(2));
		assertTrue(taskTree.getTaskMap().containsKey(3));
		assertTrue(taskTree.getTaskMap().containsKey(4));
		assertTrue(taskTree.getTaskMap().containsKey(5));
		assertTrue(taskTree.getTaskMap().containsKey(6));
		assertTrue(taskTree.getTaskMap().containsKey(7));
		assertTrue(taskTree.getTaskMap().containsKey(8));
				
		// expect the sizes to be equal
		int count = TaskTree.getInstance().getTopLevelTasklist().size();
		assertEquals(4, count);

		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test: getting flat tasklist when the tasktree is empty
	 */
	@Test
	public void testTaskTreeGetFlatTasklist1() {

		int count = TaskTree.getInstance().getFlatTasklist().size();
		assertEquals(0, count);
	}
	
	/**
	 * test:  getting flat tasklist when the tasktree contains only top level tasks
	 */
	@Test 
	public void testTaskTreeGetFlatTasklist2() {
		
		// create a file
		String filename = "test.xml";
		
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		
		content += "<data>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The second iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>5</duration>\n";
		content += "\t\t<deadline>2012-01-30</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>3</id>\n";
		content += "\t\t<title>Iteration 3</title>\n";
		content += "\t\t<description>The third iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>19</duration>\n";
		content += "\t\t<deadline>2012-01-30</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 3</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(filename));
		// expect empty task and people tables 
		assertEquals(3, taskTree.getTasklist().size());
				
		// expect the sizes to be equal
		int count = TaskTree.getInstance().getFlatTasklist().size();
		assertEquals(3, count);

		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test: getting flat tasklist when the tasktree contains different levels of  tasks
	 */
	@Test  
	public void testTaskTreeGetFlatTasklist3() {
		
		// create a file
		String filename = "test.xml";
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The second iteration of the project, including design document and source code</description>\n";
		content += "\t\t<duration>4</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Design document</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t\t<subtasks>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>3</id>\n";
		content += "\t\t\t\t<title>Iteration 2.1</title>\n";
		content += "\t\t\t\t<description>21 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>21 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>4</id>\n";
		content += "\t\t\t\t<title>Iteration 2.2</title>\n";
		content += "\t\t\t\t<description>22 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>22 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t<subtasks>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>5</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.1</title>\n";
		content += "\t\t\t\t\t\t<description>221 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>221 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>6</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.2</title>\n";
		content += "\t\t\t\t\t\t<description>222 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>222 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t</subtasks>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t</subtasks>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>7</id>\n";
		content += "\t\t<title>Iteration 3</title>\n";
		content += "\t\t<description>The third iteration of the project, including test plan, report document and source code</description>\n";
		content += "\t\t<duration>30</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Test plan and report document</deliverable>\n";
		content += "\t\t<person>Person 3</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>8</id>\n";
		content += "\t\t<title>Iteration 4</title>\n";
		content += "\t\t<description>The final iteration of the project (complete system)</description>\n";
		content += "\t\t<duration>14</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Complete system</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";
		
		createFile(filename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(filename));
		
		// make sure the tasks and subtasks were added based on their IDs
		assertTrue(taskTree.getTaskMap().containsKey(1));
		assertTrue(taskTree.getTaskMap().containsKey(2));
		assertTrue(taskTree.getTaskMap().containsKey(3));
		assertTrue(taskTree.getTaskMap().containsKey(4));
		assertTrue(taskTree.getTaskMap().containsKey(5));
		assertTrue(taskTree.getTaskMap().containsKey(6));
		assertTrue(taskTree.getTaskMap().containsKey(7));
		assertTrue(taskTree.getTaskMap().containsKey(8));
				
		// expect the sizes to be equal
		int count = TaskTree.getInstance().getFlatTasklist().size();
		assertEquals(8, count);

		// clean up
		deleteFile(filename);
	}
	
	/**
	 * test saving task tree into a XML file; where the filename is null
	 *  
	 * expect an unsuccessful operation and that no XML file is created
	 */
	@Test
	public void testTaskTreeSaveXMLFile1() {
		String filename = null;
		TaskTree taskTree = TaskTree.getInstance();
		assertFalse(taskTree.saveXMLFile(filename));
	}
	
	/**
	 * test saving task Tree into an XML file; where the filename is an empty string
	 *  
	 * expect an unsuccessful operation and that no XML file is created
	 */
	@Test
	public void testTaskTreeSaveXMLFile2() {
		String filename = "";
		TaskTree taskTree = TaskTree.getInstance();
		assertFalse(taskTree.saveXMLFile(filename));
	}
	
	/**
	 * test saving task tree into a XML file; where the file already exist
	 *  
	 * expect a successful operation and that the content of the file is overwritten with the content of the task tree
	 */
	@Test
	public void testTaskTreeSaveXMLFile3() {
		
		// create an input xml file and an output xml file
		String infilename = "test.xml";
		String outFilename = "out.xml";
		
		// create input xml file
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>des1</description>\n";
		content += "\t\t<duration>1</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>des2</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";

		createFile(infilename, content);
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(infilename));
		
		// expect the successful population of tasks and person
		assertEquals(taskTree.getTasklist().size(), 2);
		
		// save the task tree into an xml file
		assertTrue(taskTree.saveXMLFile(outFilename));
		assertTrue(fileExists(outFilename));
		
		// verify the content of the xml file
		String cont = null;
		cont = loadFileContent(outFilename);
		
		String expeted = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
		expeted += "<data>\n";
		expeted += "<task>\n";
		expeted += "<id>1</id>\n";
		expeted += "<title>Iteration 1</title>\n";
		expeted += "<description>des1</description>\n";
		expeted += "<duration>1</duration>\n";
		expeted += "<deadline>2012-01-27</deadline>\n";
		expeted += "<deliverable>del1</deliverable>\n";
		expeted += "<person>Person 1</person>\n";
		expeted += "<before>-1</before>\n";
		expeted += "</task>\n";
		
		expeted += "<task>\n";
		expeted += "<id>2</id>\n";
		expeted += "<title>Iteration 2</title>\n";
		expeted += "<description>des2</description>\n";
		expeted += "<duration>2</duration>\n";
		expeted += "<deadline>2012-01-27</deadline>\n";
		expeted += "<deliverable>del1</deliverable>\n";
		expeted += "<person>Person 2</person>\n";
		expeted += "<before>-1</before>\n";
		expeted += "</task>\n";
		expeted += "</data>\n";
		
		cont = cont.replaceAll("[^\\p{L}]", "");
		expeted = expeted.replaceAll("[^\\p{L}]", "");
		assertTrue(cont.equals(expeted));
		
		deleteFile(infilename);
		deleteFile(outFilename);
	}
	
	/**
	 * test saving task tree into a xml file; when the task tree is empty
	 *  
	 * expect a successful operation and that the content of the file is only a header
	 */
	@Test
	public void testTaskTreeSaveXMLFile4(){
		
		String outFilename = "out.xml";
		// make sure the task tree is empty
		TaskTree taskTree = TaskTree.getInstance();
		assertEquals(taskTree.getTasklist().size(), 0);
		
		// save the task tree to a xml file
		assertTrue(taskTree.saveXMLFile(outFilename));
		assertTrue(fileExists(outFilename));
		
		// verify that the content is only the header
		String cont = loadFileContent(outFilename);
		
		String expeted = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
		expeted += "<data/>\n";
		
		cont = cont.replaceAll("[^\\p{L}]", "");
		expeted = expeted.replaceAll("[^\\p{L}]", "");
		assertEquals(cont, expeted);
		
		// clean up
		deleteFile(outFilename);
	}
	
	/**
	 * test saving a non-empty task tree that contains only top level tasks into a XML file
	 *  
	 * expect a successful operation and that the content of the file contains a header and the tasks
	 */
	@Test
	public void testTaskTreeSaveXMLFile5() {
		// create an input xml file and an output xml file
		String infilename = "test.xml";
		String outFilename = "out.xml";
		
		// create input xml file
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>des1</description>\n";
		content += "\t\t<duration>1</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>des2</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>del1</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";

		createFile(infilename, content);
		createFile(outFilename, "");  // create an output file
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(infilename));
		
		// expect the successful population of tasks and person
		assertEquals(taskTree.getTasklist().size(), 2);
		
		// save the task tree into an xml file
		assertTrue(taskTree.saveXMLFile(outFilename));
		assertTrue(fileExists(outFilename));
		
		// verify the content of the xml file
		String cont = null;
		cont = loadFileContent(outFilename);
		
		String expeted = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
		expeted += "<data>\n";
		expeted += "<task>\n";
		expeted += "<id>1</id>\n";
		expeted += "<title>Iteration 1</title>\n";
		expeted += "<description>des1</description>\n";
		expeted += "<duration>1</duration>\n";
		expeted += "<deadline>2012-01-27</deadline>\n";
		expeted += "<deliverable>del1</deliverable>\n";
		expeted += "<person>Person 1</person>\n";
		expeted += "<before>-1</before>\n";
		expeted += "</task>\n";
		
		expeted += "<task>\n";
		expeted += "<id>2</id>\n";
		expeted += "<title>Iteration 2</title>\n";
		expeted += "<description>des2</description>\n";
		expeted += "<duration>2</duration>\n";
		expeted += "<deadline>2012-01-27</deadline>\n";
		expeted += "<deliverable>del1</deliverable>\n";
		expeted += "<person>Person 2</person>\n";
		expeted += "<before>-1</before>\n";
		expeted += "</task>\n";
		expeted += "</data>\n";
		cont = cont.replaceAll("[^\\p{L}]", "");
		expeted = expeted.replaceAll("[^\\p{L}]", "");
		assertTrue(cont.equals(expeted));
		
		deleteFile(infilename);
		deleteFile(outFilename);
	}
	
	/**
	 * test saving a non-empty task tree that contains tasks and subtasks into a XML file
	 *  
	 * expect a successful operation and that the content of the file contains a header, all tasks, all subtasks
	 */
	@Test
	public void testTaskTreeSaveXMLFile6() {
		// create an input xml file and an output xml file
		String infilename = "test.xml";
		String outFilename = "out.xml";
		
		// create input xml file
		String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 
		content += "<data>\n";
		content += "\t<task>\n";
		content += "\t\t<id>1</id>\n";
		content += "\t\t<title>Iteration 1</title>\n";
		content += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		content += "\t\t<duration>2</duration>\n";
		content += "\t\t<deadline>2012-01-27</deadline>\n";
		content += "\t\t<deliverable>Requirements document</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>2</id>\n";
		content += "\t\t<title>Iteration 2</title>\n";
		content += "\t\t<description>The second iteration of the project, including design document and source code</description>\n";
		content += "\t\t<duration>4</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Design document</deliverable>\n";
		content += "\t\t<person>Person 2</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t\t<subtasks>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>3</id>\n";
		content += "\t\t\t\t<title>Iteration 2.1</title>\n";
		content += "\t\t\t\t<description>21 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>21 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t\t<subtask>\n";
		content += "\t\t\t\t<id>4</id>\n";
		content += "\t\t\t\t<title>Iteration 2.2</title>\n";
		content += "\t\t\t\t<description>22 description</description>\n";
		content += "\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t<deliverable>22 deliverable</deliverable>\n";
		content += "\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t<subtasks>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>5</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.1</title>\n";
		content += "\t\t\t\t\t\t<description>221 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>221 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t\t<subtask>\n";
		content += "\t\t\t\t\t\t<id>6</id>\n";
		content += "\t\t\t\t\t\t<title>Iteration 2.2.2</title>\n";
		content += "\t\t\t\t\t\t<description>222 description</description>\n";
		content += "\t\t\t\t\t\t<duration>1</duration>\n";
		content += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t\t\t\t\t<deliverable>222 deliverable</deliverable>\n";
		content += "\t\t\t\t\t\t<person>Person 2</person>\n";
		content += "\t\t\t\t\t\t<before>-1</before>\n";
		content += "\t\t\t\t\t</subtask>\n";
		content += "\t\t\t\t</subtasks>\n";
		content += "\t\t\t</subtask>\n";
		content += "\t\t</subtasks>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>7</id>\n";
		content += "\t\t<title>Iteration 3</title>\n";
		content += "\t\t<description>The third iteration of the project, including test plan, report document and source code</description>\n";
		content += "\t\t<duration>30</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Test plan and report document</deliverable>\n";
		content += "\t\t<person>Person 3</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "\t<task>\n";
		content += "\t\t<id>8</id>\n";
		content += "\t\t<title>Iteration 4</title>\n";
		content += "\t\t<description>The final iteration of the project (complete system)</description>\n";
		content += "\t\t<duration>14</duration>\n";
		content += "\t\t<deadline>2012-02-24</deadline>\n";
		content += "\t\t<deliverable>Complete system</deliverable>\n";
		content += "\t\t<person>Person 1</person>\n";
		content += "\t\t<before>-1</before>\n";
		content += "\t</task>\n";
		content += "</data>\n";

		createFile(infilename, content);
		createFile(outFilename, "");  // create an output file
		
		// load the xml file
		TaskTree taskTree = TaskTree.getInstance();
		assertTrue(taskTree.loadXMLFile(infilename));
		
		// expect the successful population of tasks and person
		assertEquals(8, taskTree.getFlatTasklist().size());
		
		// save the task tree into an xml file
		assertTrue(taskTree.saveXMLFile(outFilename));
		assertTrue(fileExists(outFilename));
		
		// verify the content of the xml file
		String cont = null;
		cont = loadFileContent(outFilename);
		
		String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"; 
		expected += "<data>\n";
		expected += "\t<task>\n";
		expected += "\t\t<id>1</id>\n";
		expected += "\t\t<title>Iteration 1</title>\n";
		expected += "\t\t<description>The first iteration of the project, including requirements document and source code</description>\n";
		expected += "\t\t<duration>2</duration>\n";
		expected += "\t\t<deadline>2012-01-27</deadline>\n";
		expected += "\t\t<deliverable>Requirements document</deliverable>\n";
		expected += "\t\t<person>Person 1</person>\n";
		expected += "\t\t<before>-1</before>\n";
		expected += "\t</task>\n";
		expected += "\t<task>\n";
		expected += "\t\t<id>2</id>\n";
		expected += "\t\t<title>Iteration 2</title>\n";
		expected += "\t\t<description>The second iteration of the project, including design document and source code</description>\n";
		expected += "\t\t<duration>4</duration>\n";
		expected += "\t\t<deadline>2012-02-24</deadline>\n";
		expected += "\t\t<deliverable>Design document</deliverable>\n";
		expected += "\t\t<person>Person 2</person>\n";
		expected += "\t\t<before>-1</before>\n";
		expected += "\t\t<subtasks>\n";
		expected += "\t\t\t<subtask>\n";
		expected += "\t\t\t\t<id>3</id>\n";
		expected += "\t\t\t\t<title>Iteration 2.1</title>\n";
		expected += "\t\t\t\t<description>21 description</description>\n";
		expected += "\t\t\t\t<duration>1</duration>\n";
		expected += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		expected += "\t\t\t\t<deliverable>21 deliverable</deliverable>\n";
		expected += "\t\t\t\t<person>Person 2</person>\n";
		expected += "\t\t\t\t<before>-1</before>\n";
		expected += "\t\t\t</subtask>\n";
		expected += "\t\t\t<subtask>\n";
		expected += "\t\t\t\t<id>4</id>\n";
		expected += "\t\t\t\t<title>Iteration 2.2</title>\n";
		expected += "\t\t\t\t<description>22 description</description>\n";
		expected += "\t\t\t\t<duration>1</duration>\n";
		expected += "\t\t\t\t<deadline>2012-02-24</deadline>\n";
		expected += "\t\t\t\t<deliverable>22 deliverable</deliverable>\n";
		expected += "\t\t\t\t<person>Person 2</person>\n";
		expected += "\t\t\t\t<before>-1</before>\n";
		expected += "\t\t\t\t<subtasks>\n";
		expected += "\t\t\t\t\t<subtask>\n";
		expected += "\t\t\t\t\t\t<id>5</id>\n";
		expected += "\t\t\t\t\t\t<title>Iteration 2.2.1</title>\n";
		expected += "\t\t\t\t\t\t<description>221 description</description>\n";
		expected += "\t\t\t\t\t\t<duration>1</duration>\n";
		expected += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		expected += "\t\t\t\t\t\t<deliverable>221 deliverable</deliverable>\n";
		expected += "\t\t\t\t\t\t<person>Person 2</person>\n";
		expected += "\t\t\t\t\t\t<before>-1</before>\n";
		expected += "\t\t\t\t\t</subtask>\n";
		expected += "\t\t\t\t\t<subtask>\n";
		expected += "\t\t\t\t\t\t<id>6</id>\n";
		expected += "\t\t\t\t\t\t<title>Iteration 2.2.2</title>\n";
		expected += "\t\t\t\t\t\t<description>222 description</description>\n";
		expected += "\t\t\t\t\t\t<duration>1</duration>\n";
		expected += "\t\t\t\t\t\t<deadline>2012-02-24</deadline>\n";
		expected += "\t\t\t\t\t\t<deliverable>222 deliverable</deliverable>\n";
		expected += "\t\t\t\t\t\t<person>Person 2</person>\n";
		expected += "\t\t\t\t\t\t<before>-1</before>\n";
		expected += "\t\t\t\t\t</subtask>\n";
		expected += "\t\t\t\t</subtasks>\n";
		expected += "\t\t\t</subtask>\n";
		expected += "\t\t</subtasks>\n";
		expected += "\t</task>\n";
		expected += "\t<task>\n";
		expected += "\t\t<id>7</id>\n";
		expected += "\t\t<title>Iteration 3</title>\n";
		expected += "\t\t<description>The third iteration of the project, including test plan, report document and source code</description>\n";
		expected += "\t\t<duration>30</duration>\n";
		expected += "\t\t<deadline>2012-02-24</deadline>\n";
		expected += "\t\t<deliverable>Test plan and report document</deliverable>\n";
		expected += "\t\t<person>Person 3</person>\n";
		expected += "\t\t<before>-1</before>\n";
		expected += "\t</task>\n";
		expected += "\t<task>\n";
		expected += "\t\t<id>8</id>\n";
		expected += "\t\t<title>Iteration 4</title>\n";
		expected += "\t\t<description>The final iteration of the project (complete system)</description>\n";
		expected += "\t\t<duration>14</duration>\n";
		expected += "\t\t<deadline>2012-02-24</deadline>\n";
		expected += "\t\t<deliverable>Complete system</deliverable>\n";
		expected += "\t\t<person>Person 1</person>\n";
		expected += "\t\t<before>-1</before>\n";
		expected += "\t</task>\n";
		expected += "</data>\n";
		
		cont = cont.replaceAll("[^\\p{L}]", "");
		expected = expected.replaceAll("[^\\p{L}]", "");
		assertTrue(cont.equals(expected));		
		deleteFile(infilename);
		deleteFile(outFilename);
	}
}